package com.lancoo.ccas53.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.entity.*;
import com.lancoo.ccas53.mapper.MonitorMapper;
import com.lancoo.ccas53.pojo.dto.ResultDto;
import com.lancoo.ccas53.service.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 合理性监测表 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
public class MonitorServiceImpl extends ServiceImpl<MonitorMapper, Monitor> implements MonitorService {
    @Resource
    private TeachingClassService teachingClassService;
    @Resource
    private TeachingClassWeekService teachingClassWeekService;
    @Resource
    private MonitorRecordService monitorRecordService;
    @Resource
    private TeachingClassTeacherService teachingClassTeacherService;
    @Resource
    private CourseService courseService;
    @Resource
    private TeacherService teacherService;

    @Override
    public ResultDto<Monitor> getMonitor(Integer taskId, String baseCollegeId, Integer pageSize, Integer currentPage) {
        ResultDto<Monitor> result = new ResultDto<>();
        result.setCurrentPage(currentPage);
        result.setPageSize(pageSize);
        Page<Monitor> page = new Page<>(currentPage, pageSize);
        List<Monitor> monitorList = this.lambdaQuery()
                .eq(Monitor::getTaskId, taskId)
                .eq(StringUtils.isNotBlank(baseCollegeId), Monitor::getBaseCollegeId, baseCollegeId)
                .page(page)
                .getRecords();
        //按监测时间倒序
        monitorList.sort(Comparator.comparing(Monitor::getCreatedTime).reversed());
        result.setList(monitorList);
        result.setTotal(page.getTotal());
        result.setPages(page.getPages());
        return result;
    }

    @Override
    public List<MonitorRecord> addMonitor(Integer taskId, String baseCollegeId, String userId, String userName, Monitor param) {
        List<MonitorRecord> result = new ArrayList<>();
        this.save(param.setTaskId(taskId));
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).list();
        List<Long> teachingClassIdCollect = teachingClassList.stream().map(TeachingClass::getTeachingClassId).collect(Collectors.toList());
        List<TeachingClassWeek> weekList = teachingClassWeekService.lambdaQuery().in(TeachingClassWeek::getTeachingClassId, teachingClassIdCollect).list();
        List<TeachingClassTeacher> classTeacherList = teachingClassTeacherService.lambdaQuery().in(TeachingClassTeacher::getTeachingClassId, teachingClassIdCollect).list();
        List<Course> courseList = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list();
        List<Long> courseIdList = teachingClassList.stream().map(TeachingClass::getCourseId).collect(Collectors.toList());
        List<Teacher> teacherList = teacherService.lambdaQuery().eq(Teacher::getTaskId, taskId).list();

        //检测课程最大周学时数
        if (ObjUtil.isNotEmpty(param.getMaxWeekNum())) {
            for (TeachingClassWeek item : weekList) {
                if (item.getWeekNum() != null && item.getWeekNum() > param.getMaxWeekNum()) {
                    //生成检测数据实体类
                    MonitorRecord record = new MonitorRecord()
                            .setTaskId(taskId)
                            .setMonitorId(param.getMonitorId())
                            .setType(2)
                            .setMonitorThreshold(param.getMaxWeekNum())
                            .setMonitorValue(item.getWeekNum().toString())
                            .setTeachingClassId(item.getTeachingClassId());

                    teachingClassList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).findFirst()
                            .ifPresent(a -> record.setTeachingClassName(a.getTeachingClassName()));
                    result.add(record);
                }
            }
        }
        //检测最大连上节次
        if (ObjUtil.isNotEmpty(param.getMaxConnectSection())) {
            for (TeachingClassWeek item : weekList) {
                if (item.getConnectSection() != null && item.getConnectSection() > param.getMaxConnectSection()) {
                    //生成检测数据实体类
                    MonitorRecord record = new MonitorRecord()
                            .setTaskId(taskId)
                            .setMonitorId(param.getMonitorId())
                            .setType(1)
                            .setMonitorThreshold(param.getMaxConnectSection())
                            .setMonitorValue(item.getConnectSection().toString())
                            .setTeachingClassId(item.getTeachingClassId());

                    teachingClassList.stream().filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId())).findFirst()
                            .ifPresent(a -> record.setTeachingClassName(a.getTeachingClassName()));
                    result.add(record);
                }
            }
        }
        //检测课程最大任课教师数
        if (ObjUtil.isNotEmpty(param.getMaxTeacherNum())) {
            for (Course course : courseList) {
                List<TeachingClass> classList = teachingClassList.stream().filter(a -> a.getCourseId().equals(course.getCourseId())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(classList)) {
                    for (TeachingClass teachingClass : classList) {
                        StringBuilder teacherName = new StringBuilder();
                        int teacherNum = 0;
                        List<TeachingClassTeacher> list = classTeacherList.stream().filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId())).collect(Collectors.toList());
                        for (TeachingClassTeacher item : list) {
                            Optional<Teacher> optional = teacherList.stream().filter(a -> a.getTeacherId().equals(item.getTeacherId()) && a.getIdentity().equals(1)).findFirst();
                            if (optional.isPresent()) {
                                teacherNum += 1;
                                teacherName.append(optional.get().getTeacherName());
                                teacherName.append(",");
                            }
                        }
                        if (teacherName.length() > 1) {
                            teacherName.setLength(teacherName.length() - 1);
                        }
                        if (teacherNum > param.getMaxTeacherNum()) {
                            //生成检测数据实体类
                            MonitorRecord record = new MonitorRecord()
                                    .setTaskId(taskId)
                                    .setMonitorId(param.getMonitorId())
                                    .setType(3)
                                    .setMonitorThreshold(param.getMaxTeacherNum())
                                    .setMonitorValue(teacherName.toString())
                                    .setTeachingClassId(teachingClass.getTeachingClassId())
                                    .setTeachingClassName(teachingClass.getTeachingClassName());
                            result.add(record);
                        }
                    }
                }
            }
        }
        //检测课程最大助教教师数
        if (ObjUtil.isNotEmpty(param.getMaxAssistantNum())) {
            for (Course course : courseList) {
                List<TeachingClass> classList = teachingClassList.stream().filter(a -> a.getCourseId().equals(course.getCourseId())).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(classList)) {
                    for (TeachingClass teachingClass : classList) {
                        int teacherNum = 0;
                        StringBuilder teacherName = new StringBuilder();
                        List<TeachingClassTeacher> list = classTeacherList.stream().filter(a -> a.getTeachingClassId().equals(teachingClass.getTeachingClassId())).collect(Collectors.toList());
                        for (TeachingClassTeacher item : list) {
                            Optional<Teacher> optional = teacherList.stream().filter(a -> a.getTeacherId().equals(item.getTeacherId()) && a.getIdentity().equals(2)).findFirst();
                            if (optional.isPresent()) {
                                teacherNum += 1;
                                teacherName.append(optional.get().getTeacherName());
                                teacherName.append(",");
                            }
                        }
                        if (teacherName.length() > 1) {
                            teacherName.setLength(teacherName.length() - 1);
                        }
                        if (teacherNum > param.getMaxAssistantNum()) {
                            //生成检测数据实体类
                            MonitorRecord record = new MonitorRecord()
                                    .setTaskId(taskId)
                                    .setMonitorId(param.getMonitorId())
                                    .setType(4)
                                    .setMonitorThreshold(param.getMaxAssistantNum())
                                    .setMonitorValue(teacherName.toString())
                                    .setTeachingClassId(teachingClass.getTeachingClassId())
                                    .setTeachingClassName(teachingClass.getTeachingClassName());
                            result.add(record);
                        }
                    }
                }
            }
        }
        //检测每周教师最大上课节次
        if (ObjUtil.isNotEmpty(param.getMaxTeacherWeekNum())) {
            //教师id
            List<Long> teacherIdList = classTeacherList.stream().map(TeachingClassTeacher::getTeacherId).distinct().collect(Collectors.toList());
            for (Long teacherId : teacherIdList) {
                List<TeachingClassTeacher> list = classTeacherList.stream().filter(a -> a.getTeacherId().equals(teacherId)).collect(Collectors.toList());
                //教学班id
                List<Long> teachingClassIds = list.stream().map(TeachingClassTeacher::getTeachingClassId).collect(Collectors.toList());
                //教师上课节次
                int weekNum = 0;
                for (Long teachingClassId : teachingClassIds) {
                    Optional<TeachingClassWeek> optional = weekList.stream().filter(a -> a.getTeachingClassId().equals(teachingClassId)).findFirst();
                    if (optional.isPresent()) {
                        weekNum += optional.get().getConnectSection();
                    }
                }
                if (weekNum > param.getMaxTeacherWeekNum()) {
                    for (Long teachingClassId : teachingClassIds) {
                        Optional<TeachingClass> teachingClassOptional = teachingClassList.stream().filter(a -> a.getTeachingClassId().equals(teachingClassId)).findFirst();
                        if (teachingClassOptional.isPresent()) {
                            TeachingClass model = teachingClassOptional.get();
                            //生成检测数据实体类
                            MonitorRecord record = new MonitorRecord()
                                    .setTaskId(taskId)
                                    .setMonitorId(param.getMonitorId())
                                    .setType(5)
                                    .setMonitorThreshold(param.getMaxTeacherWeekNum())
                                    .setMonitorValue(String.valueOf(weekNum))
                                    .setTeachingClassId(teachingClassId)
                                    .setTeachingClassName(model.getTeachingClassName());
                            teacherList.stream().filter(a -> a.getTeacherId().equals(teacherId)).findFirst().ifPresent(a -> record.setTeacherName(a.getTeacherName()));
                            result.add(record);
                        }
                    }
                }
            }
        }
        //检测教学班最低上课人数
        if (ObjUtil.isNotEmpty(param.getMinStudentNum())) {
            for (TeachingClass item : teachingClassList) {
                if (item.getClassNum() != null && item.getClassNum() < param.getMinStudentNum()) {
                    //生成检测数据实体类
                    MonitorRecord record = new MonitorRecord()
                            .setTaskId(taskId)
                            .setMonitorId(param.getMonitorId())
                            .setType(6)
                            .setMonitorThreshold(param.getMinStudentNum())
                            .setMonitorValue(item.getClassNum().toString())
                            .setTeachingClassId(item.getTeachingClassId())
                            .setTeachingClassName(item.getTeachingClassName());
                    result.add(record);
                }
            }
        }
        monitorRecordService.saveBatch(result);
        return result;
    }

    //异步检测
    @Override
    public void checkWeekNum(Integer maxWeekNum, Integer taskId, Integer monitorId) {
        List<TeachingClassWeek> weekList = teachingClassWeekService.lambdaQuery().list();
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery()
                .eq(TeachingClass::getTaskId, taskId)
                .list();
        for (TeachingClassWeek item : weekList) {
            if (item.getWeekNum() != null && item.getWeekNum() > maxWeekNum) {
                //生成检测数据实体类
                MonitorRecord record = new MonitorRecord()
                        .setTaskId(taskId)
                        .setMonitorId(monitorId)
                        .setType(2)
                        .setMonitorThreshold(maxWeekNum)
                        .setMonitorValue(item.getWeekNum().toString())
                        .setTeachingClassId(item.getTeachingClassId());

                teachingClassList.stream()
                        .filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId()))
                        .findFirst()
                        .ifPresent(a -> record.setTeachingClassName(a.getTeachingClassName()));
                monitorRecordService.save(record);
            }
        }
    }

    @Override
    public void checkConnectSection(Integer maxConnectSection, Integer taskId, Integer monitorId) {
        List<TeachingClassWeek> weekList = teachingClassWeekService.lambdaQuery().list();
        List<TeachingClass> teachingClassList = teachingClassService.lambdaQuery().eq(TeachingClass::getTaskId, taskId).list();
        for (TeachingClassWeek item : weekList) {
            if (item.getConnectSection() != null && item.getConnectSection() > maxConnectSection) {
                //生成检测数据实体类
                MonitorRecord record = new MonitorRecord()
                        .setTaskId(taskId)
                        .setMonitorId(monitorId)
                        .setType(1)
                        .setMonitorThreshold(maxConnectSection)
                        .setMonitorValue(item.getConnectSection().toString())
                        .setTeachingClassId(item.getTeachingClassId());

                teachingClassList.stream()
                        .filter(a -> a.getTeachingClassId().equals(item.getTeachingClassId()))
                        .findFirst()
                        .ifPresent(a -> record.setTeachingClassName(a.getTeachingClassName()));
                monitorRecordService.save(record);
            }
        }
    }

    @Override
    public void checkTeacherNum(Integer maxWeekNum, Integer taskId, Integer monitorId) {

    }

    @Override
    public void checkAssistantNum(Integer maxWeekNum, Integer taskId, Integer monitorId) {

    }

    @Override
    public void checkTeacherWeekNum(Integer maxWeekNum, Integer taskId, Integer monitorId) {

    }

    @Override
    public void checkStudentNum(Integer maxWeekNum, Integer taskId, Integer monitorId) {

    }

    @Override
    public List<MonitorRecord> getMonitorRecord(Integer taskId, Integer monitorId) {
        return monitorRecordService.lambdaQuery()
                .eq(MonitorRecord::getMonitorId, monitorId)
                .eq(MonitorRecord::getTaskId, taskId)
                .list();
    }


}
